package com.innovations.framework.sms.service.impl;

import com.innovations.common.core.redis.RedisCache;
import com.innovations.framework.sms.CustomConfig;
import com.innovations.framework.sms.SmsRequest;
import com.innovations.framework.sms.service.SmsService;
import com.innovations.system.service.ISysUserService;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

@Service
public class SmsServiceImpl implements SmsService {

    private static final Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);
    private final RestTemplate restTemplate;
    @Autowired
    ISysUserService sysUserService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private CustomConfig config;
    @Autowired
    public SmsServiceImpl(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    // 是否启用短信发送
    @Value("${sms.enabled}")
    private boolean smsEnabled;


    /**
     * 发送短信验证码
     *
     * @param phone 手机号
     * @return 发送是否成功
     */
    @Override
    public String sendVerification(String phone) {
        // 根据redis判断是否发送过验证码
        if (redisCache.hasKey(phone)) {
            logger.warn("验证码已发送，稍等再试: 手机号={}", phone);
            throw new RuntimeException("验证码已发送，稍等再试！" + phone);
        }
        // 校验手机号格式
        if (phone == null || phone.length() != 11 || !phone.matches("^1[3-9]\\d{9}$")) {
            logger.error("无效的输入参数: 手机号={}", phone);
            throw new RuntimeException("无效的输入参数！" + phone);
        }
        // 生成验证码
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
        logger.info("测试yz：{}", code);
        // 将验证码存储到redis中，1分钟不允许重复发送，验证码5分钟过期
        redisCache.setCacheObject(phone, code, 1, java.util.concurrent.TimeUnit.MINUTES);
        redisCache.setCacheObject("yzm" + phone, code, 5, java.util.concurrent.TimeUnit.MINUTES);
        // 发送短信
        Map<String, String> params = new HashMap<>();
        params.put("code", code);
        sendSms(phone, config.getTemplateCode(), params);
        return "";
    }

    /**
     * 核验验证码
     *
     * @param phone   手机号
     * @param smsCode 验证码
     * @return 校验结果
     */
    @Override
    public Boolean checkVerificationCode(String phone, String smsCode) {
        // 根据redis判断是否发送过验证码
        if (!redisCache.hasKey("yzm" + phone)) {
            logger.warn("验证失败，验证码未发送或已失效！", phone);
            throw new RuntimeException("验证码未发送或已失效");
        } else if (!redisCache.getCacheObject("yzm" + phone).equals(smsCode)) {
            logger.warn("验证失败，验证码错误: 手机号={}", phone);
            throw new RuntimeException("验证码错误");
        }
        logger.info("验证成功: 手机号={}", phone);
        return true;
    }

    /**
     * 发送业务通知短信
     *
     * @param phone      手机号
     * @param templateId 模板ID
     * @param params     模板参数
     * @return 发送是否成功
     */
    @Override
    public String sendNotification(String phone, String templateId, Map<String, String> params) {
        if (phone == null || phone.isEmpty() || templateId == null || templateId.isEmpty() || params == null) {
            logger.error("无效的输入参数: 手机号={}, 模板ID={}, 参数={}", phone, templateId, params);
            return "";
        }
        sendSms(phone, templateId, params);
        return "";
    }

    /**
     * 发送短信
     *
     * @param phone        手机号
     * @param templateCode 模板ID
     * @param params       模板参数
     * @return 发送是否成功
     */
    private void sendSms(String phone, String templateCode, Map<String, String> params) {
        try {
            if (smsEnabled) {
                // 设置请求头
                HttpHeaders headers = new HttpHeaders();
                headers.set("Authorization", "Bearer " + config.getAppKey());
                headers.set("Content-Type", "application/json");

                // 构建请求体
                SmsRequest smsRequest = new SmsRequest(config.getAppId(), config.getAppKey(), phone, templateCode, params.get("code"));
                HttpEntity<SmsRequest> request = new HttpEntity<>(smsRequest, headers);

                // 发送请求
                ResponseEntity<String> response = restTemplate.exchange(
                        config.getApiUrl(),
                        HttpMethod.POST,
                        request,
                        String.class
                );

                // 检查响应状态码
                if (response.getStatusCode() == HttpStatus.OK) {
                    logger.info("短信发送成功: 手机号={}", phone);
                } else {
                    logger.error("短信发送失败: 手机号={}, 状态码={}", phone, response.getStatusCodeValue());
                    throw new RuntimeException("短信发送失败！" + phone);
                }
            }
            logger.error("未启用短信功能");
        } catch (RestClientException e) {
            logger.error("发送短信时发生错误: 手机号={}", phone, e);
            throw new RuntimeException("发送短信时发生错误！" + phone);
        }
    }
}
